package com.sumer.psychology.blog.resource;

import com.sumer.psychology.blog.application.command.*;
import com.sumer.psychology.blog.domain.model.BlogId;
import com.sumer.psychology.blog.domain.model.CategoryId;
import com.sumer.psychology.common.application.ApplicationServiceRegistry;
import com.sumer.psychology.common.resource.AbstractResource;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

/**
 * 博客资源
 * <p/>
 * User: zhenguang.zhu
 * Date: 2014/9/12
 * Time: 14:49
 */
@Path("/v1/blog/")
@Consumes(MediaType.APPLICATION_JSON)
public class BlogResource extends AbstractResource {
    //private static Logger logger = LoggerFactory.getLogger(BlogResource.class);

    @Context
    private UriInfo uriInfo;

    /**
     * 新增blog
     *
     * @param aCreateBlogCommand command
     * @return response
     */
    @POST
    public Response addBlog(CreateBlogCommand aCreateBlogCommand) {
        checkAuthorAndRole(aCreateBlogCommand);

        BlogId blogId = ApplicationServiceRegistry
                .blogApplicationService()
                .newBlog(aCreateBlogCommand);

        return Response
                .status(Response.Status.CREATED)
                .location(uriInfo.getAbsolutePath())
                .entity(savedId(blogId.identity()))
                .build();
    }

    /**
     * 修改blog
     *
     * @param aChangeBlogCommand command
     * @param aBlogId            blog id
     * @return response
     */
    @PUT
    @Path("{blogId}")
    public Response changeBlog(
            ChangeBlogCommand aChangeBlogCommand,
            @PathParam("blogId") String aBlogId) {
        ApplicationServiceRegistry
                .blogApplicationService()
                .changeBlog(aChangeBlogCommand);

        return Response.status(Response.Status.ACCEPTED).build();
    }

    /**
     * blog放入回收站
     *
     * @param aPutBlogToRecycleBinCommand command
     * @return response
     */
    @POST
    @Path("recycle_bin/")
    public Response recycleBin(PutBlogToRecycleBinCommand aPutBlogToRecycleBinCommand) {
        ApplicationServiceRegistry
                .blogApplicationService()
                .recycleBin(aPutBlogToRecycleBinCommand);

        return Response.status(Response.Status.ACCEPTED).build();
    }

    /**
     * blog从回收站恢复
     *
     * @param aBlogId id
     * @return response
     */
    @DELETE
    @Path("recycle_bin/{blogId}")
    public Response restoreFromRecycleBin(@PathParam("blogId") String aBlogId) {
        ApplicationServiceRegistry
                .blogApplicationService()
                .restore(new RestoreBlogCommand(aBlogId));

        return Response.status(Response.Status.ACCEPTED).build();
    }

    /**
     * 彻底删除blog
     *
     * @param aBlogId id
     * @return response
     */
    @DELETE
    @Path("{blogId}")
    public Response deleteCompletely(@PathParam("blogId") String aBlogId) {
        ApplicationServiceRegistry
                .blogApplicationService()
                .deleteCompletely(new DeleteBlogCommand(aBlogId));

        return Response.status(Response.Status.ACCEPTED).build();
    }

    /**
     * 新增一个分类
     *
     * @param aCreateCategoryCommand command
     * @return response
     */
    @POST
    @Path("category/")
    public Response addCategory(CreateCategoryCommand aCreateCategoryCommand) {
        checkAuthorAndRole(aCreateCategoryCommand);

        CategoryId categoryId = ApplicationServiceRegistry
                .categoryApplicationService()
                .newCategory(aCreateCategoryCommand);

        return Response
                .status(Response.Status.CREATED)
                .location(uriInfo.getAbsolutePath())
                .entity(savedId(categoryId.identity()))
                .build();
    }

    /**
     * 修改分类
     *
     * @param aRenameCategoryCommand command
     * @return response
     */
    @PUT
    @Path("category/{categoryId}")
    public Response renameCategory(
            @PathParam("categoryId") String categoryId,
            RenameCategoryCommand aRenameCategoryCommand) {
        ApplicationServiceRegistry
                .categoryApplicationService()
                .rename(new RenameCategoryCommand(
                        categoryId,
                        aRenameCategoryCommand.changedName()));

        return Response.status(Response.Status.ACCEPTED).build();
    }

    /**
     * blog分类
     *
     * @param aBlogId     blog id
     * @param aCategoryId category id
     * @return response
     */
    @PUT
    @Path("category/{blogId}/{categoryId}")
    public Response blogCategorized(
            @PathParam("blogId") String aBlogId,
            @PathParam("categoryId") String aCategoryId) {
        ApplicationServiceRegistry
                .blogApplicationService()
                .categorize(new CategorizeBlogCommand(
                        aBlogId,
                        aCategoryId));

        return Response.status(Response.Status.ACCEPTED).build();
    }

    /**
     * 删除多个分类，下面的blog变为未分类
     *
     * @param categoryIdsString ids
     * @return response
     */
    @DELETE
    @Path("category/{categoryIds}")
    public Response deleteCategories(@PathParam("categoryIds") String categoryIdsString) {
        String[] categoryIds = categoryIdsString.contains(";") ?
                categoryIdsString.split(";") :
                new String[]{categoryIdsString};

        for (String categoryId : categoryIds) {
            ApplicationServiceRegistry
                    .categoryApplicationService()
                    .delete(new DeleteCategoryCommand(categoryId));
        }
        return Response.status(Response.Status.ACCEPTED).build();
    }

    /**
     * 设置为推荐贴
     *
     * @param aBlogId blog id
     * @return response
     */
    @POST
    @Path("digest_posts/{blogId}")
    public Response recommend(@PathParam("blogId") String aBlogId) {
        ApplicationServiceRegistry
                .blogApplicationService()
                .recommend(new RecommendBlogCommand(aBlogId));

        return Response
                .status(Response.Status.CREATED)
                .location(uriInfo.getAbsolutePath())
                .build();
    }

    /**
     * 删除推荐帖标志
     *
     * @param aBlogId blog id
     * @return response
     */
    @DELETE
    @Path("digest_posts/{blogId}")
    public Response cancelRecommendation(@PathParam("blogId") String aBlogId) {
        ApplicationServiceRegistry
                .blogApplicationService()
                .cancleRecommendation(new CancelBlogRecommendationCommand(aBlogId));

        return Response.status(Response.Status.ACCEPTED).build();
    }

    /**
     * 根据关键字查询文章
     *
     * @param keyword      keyword
     * @param countPerPage count per page
     * @param offset       offset
     * @return json
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response find(
            @QueryParam("keyword") String keyword,
            @QueryParam("countPerPage") int countPerPage,
            @QueryParam("offset") int offset) {
        String results = ApplicationServiceRegistry
                .blogQueryApplicationService()
                .findByKeyword(keyword, countPerPage, offset);

        return Response.ok(results).build();
    }

    /**
     * 查看精华（评论最多的）
     *
     * @param countPerPage count per page
     * @return json
     */
    @GET
    @Path("topics")
    @Produces(MediaType.APPLICATION_JSON)
    public Response findTopics(@QueryParam("countPerPage") int countPerPage) {
        String results = ApplicationServiceRegistry
                .blogQueryApplicationService()
                .displayTopics(countPerPage);

        return Response.ok(results).build();
    }

    /**
     * 查看某一篇文章
     *
     * @param blogId blog id
     * @return json
     */
    @GET
    @Path("{blogId}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response findBlogById(@PathParam("blogId") String blogId) {
        String results = ApplicationServiceRegistry
                .blogQueryApplicationService()
                .findById(blogId);

        if (results == null) {
            return Response.status(404).build();
        }
        return Response.ok(results).build();
    }

    /**
     * 查看某一作者的文章
     *
     * @param authorId     author
     * @param keyword      key word
     * @param countPerPage count per page
     * @param offset       offset
     * @return json
     */
    @GET
    @Path("author/{authorId}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response findBlogsByAuthor(
            @PathParam("authorId") String authorId,
            @QueryParam("keyword") String keyword,
            @QueryParam("countPerPage") int countPerPage,
            @QueryParam("offset") int offset) {
        String results = ApplicationServiceRegistry
                .blogQueryApplicationService()
                .findByAuthor(authorId, countPerPage, offset, keyword);

        return Response.ok(results).build();
    }

    /**
     * 查看某一作者的blog目录
     *
     * @param authorId author
     * @return json
     */
    @GET
    @Path("categories/author/{authorId}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response findCategoriesByAuthor(@PathParam("authorId") String authorId) {
        String results = ApplicationServiceRegistry
                .categoryQueryApplicationService()
                .listCategoriesOf(authorId);

        return Response.ok(results).build();
    }

    /**
     * 查看某一目录下的所有文章
     *
     * @param categoryId   category id
     * @param countPerPage count per page
     * @param offset       offset
     * @return json
     */
    @GET
    @Path("category/{categoryId}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response findBlogsOfCategory(
            @PathParam("categoryId") String categoryId,
            @QueryParam("countPerPage") int countPerPage,
            @QueryParam("offset") int offset) {
        String results = ApplicationServiceRegistry
                .blogQueryApplicationService()
                .findByCategory(categoryId, countPerPage, offset);

        return Response.ok(results).build();
    }

    /**
     * 查看所有的blog标签
     *
     * @param limit limit
     * @return json
     */
    @GET
    @Path("tags")
    @Produces(MediaType.APPLICATION_JSON)
    public Response findAllBlogTags(@QueryParam("limit") int limit) {
        String results = ApplicationServiceRegistry
                .blogTagQueryApplicationService()
                .findTags(limit);

        return Response.ok(results).build();
    }

    /**
     * 查看回收站里的blog
     *
     * @param authorId author id
     * @return json
     */
    @GET
    @Path("recycle_bin/author/{authorId}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response findBlogsOfRecycleBin(@PathParam("authorId") String authorId) {
        String results = ApplicationServiceRegistry
                .blogQueryApplicationService()
                .findOfRecycleBinByAuthor(authorId);

        return Response.ok(results).build();
    }

}
